#include "vector.h"

namespace t2c2 {

Vector::Vector(const unsigned int _row): row(_row) {
	data = new double[row];

	for(unsigned int i = 0; i < row; i++)
		data[i] = 0;
}

Vector::Vector(const Vector& _v) {
	row = _v.get_row();
	data = new double[row];

	for(unsigned int i = 0; i < row; i++)
		data[i] = _v[i];
}

Vector::~Vector() {
	delete[] data;
}

double Vector::inner_product(const Vector & _vector) const {
	double result = 0.0;

	for(unsigned int i = 0; i < row; i++)
		result += data[i] * _vector[i];
	
	return result;
}

Matrix Vector::outter_product(const Vector & _vector) const {
	Matrix result(row,_vector.get_row());

	for(unsigned int i = 0; i < row; i++) {
		for(unsigned int j = 0; j < _vector.get_row(); j++) {
			result[i][j] = data[i] * _vector[j];
		}
	}

	return result;
}

Vector Vector::scalar_product(const double & _scalar) const {
	Vector result(row);

	for(unsigned int i = 0; i < row; i++) {
		result[i] = data[i]*_scalar;
	}

	return result;
}

double Vector::length(void) const {
	return sqrt(this->inner_product((*this)));
}

Vector Vector::normalize(void) const {
	double l = this->length();
	if(l != 0) {
		return this->scalar_product( 1.0/l );
	} else {
		return Vector(row);
	}
}

unsigned int Vector::get_row(void) const {
	return row;
}

void Vector::print(void) {
	for(unsigned int i = 0; i < row; i++)
		std::cout << data[i] << std::endl;
}

Matrix Vector::to_matrix_column(void) const {
	Matrix result(row, 1);

	for(unsigned int i = 0; i < row; i++) {
		result[i][0] = data[i];
	}

	return result;
}

double& Vector::operator[](unsigned int i) const {
	if(i >= row)
		exit(1);
	
	return data[i];
}

Vector Vector::operator-() {
	return this->scalar_product(-1);
}

Vector& Vector::operator=(const Vector& _v1) {
	delete[] data;
	
	row = _v1.get_row();
	data = new double[row];

	for(unsigned int i = 0; i < row; i++)
		data[i] = _v1[i];

	return *this;
}

Vector operator+(const Vector& _v1, const Vector& _v2) {
	if(_v1.get_row() != _v2.get_row())
		exit(1);
	
	unsigned int nrow = _v1.get_row();

	Vector result(nrow);

	for(unsigned int i = 0; i < nrow; i++)
		result[i] = _v1[i] + _v2[i];

	return result;
}

Vector operator-(const Vector& _v1, const Vector& _v2) {
	if(_v1.get_row() != _v2.get_row())
		exit(1);
	
	unsigned int nrow = _v1.get_row();

	Vector result(nrow);

	for(unsigned int i = 0; i < nrow; i++)
		result[i] = _v1[i] - _v2[i];

	return result;
}

}
